From b9f9f42b3f85d0e44223e0da01344e6975b288be Mon Sep 17 00:00:00 2001 From: "maf46@burn.cl.cam.ac.uk" Date: Tue, 19 Jul 2005 10:40:26 +0000 Subject: [PATCH] Shadow mode's writable-PTs should only allow guest kernels access to PTs --- xen/arch/x86/shadow.c | 2 +- xen/arch/x86/shadow32.c | 2 +- xen/include/asm-x86/shadow.h | 11 ++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index 1d07406089..3f172d8647 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -1684,7 +1684,7 @@ static int shadow_fault_32(unsigned long va, struct cpu_user_regs *regs) if ( unlikely(!(l1e_get_flags(gpte) & _PAGE_RW)) ) { - if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) ) + if ( shadow_mode_page_writable(va, regs, l1e_get_pfn(gpte)) ) { allow_writes = 1; l1e_add_flags(gpte, _PAGE_RW); diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index 7b53efcfc6..0c0f749401 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -2612,7 +2612,7 @@ int shadow_fault(unsigned long va, struct cpu_user_regs *regs) if ( unlikely(!(l1e_get_flags(gpte) & _PAGE_RW)) ) { - if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) ) + if ( shadow_mode_page_writable(va, regs, l1e_get_pfn(gpte)) ) { allow_writes = 1; l1e_add_flags(gpte, _PAGE_RW); diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index b4a5391ddc..2ead58f983 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -1691,8 +1691,10 @@ shadow_set_l1e(unsigned long va, l1_pgentry_t new_spte, int create_l1_shadow) /************************************************************************/ static inline int -shadow_mode_page_writable(struct domain *d, unsigned long gpfn) +shadow_mode_page_writable(unsigned long va, struct cpu_user_regs *regs, unsigned long gpfn) { + struct vcpu *v = current; + struct domain *d = v->domain; unsigned long mfn = __gpfn_to_mfn(d, gpfn); u32 type = frame_table[mfn].u.inuse.type_info & PGT_type_mask; @@ -1701,11 +1703,14 @@ shadow_mode_page_writable(struct domain *d, unsigned long gpfn) type = shadow_max_pgtable_type(d, gpfn, NULL); if ( VM_ASSIST(d, VMASST_TYPE_writable_pagetables) && - (type == PGT_l1_page_table) ) + (type == PGT_l1_page_table) && + (va < HYPERVISOR_VIRT_START) && + KERNEL_MODE(v, regs) ) return 1; if ( shadow_mode_write_all(d) && - type && (type <= PGT_l4_page_table) ) + type && (type <= PGT_l4_page_table) && + KERNEL_MODE(v, regs) ) return 1; return 0; -- 2.30.2